/*---------------------------------------------------------------
    File: 
        wf_string_util.h
  
    Description:
        String utilities
        some functions are from MUD Programming - Ron Penton

    Author:
        Walter Fan    (walterfan@qq.com)                
                                                      
    History:
        1/25/2010  Create                                

----------------------------------------------------------------*/ 
#ifndef __STRING_UTIL__
#define __STRING_UTIL__
#include "common.h"
#include "wf_type.h"
#include <string.h>
#include <string>
#include <sstream>

typedef const char * LPCSTR;
typedef char * LPSTR;


#ifdef __cplusplus 
extern "C" {
#endif

    int    safe_snprintf(LPSTR s, size_t n, LPCSTR format, ...);
    LPSTR  safe_strdup(LPCSTR s);
    void   safe_strcpy(LPSTR pDest, LPSTR pSrc, int nCount);

    LPSTR  to_upper(LPSTR s);
    LPSTR  to_lower(LPSTR s);

#ifdef __cplusplus 
}
#endif

    std::string SearchAndReplace( 
        const std::string& p_target,
        const std::string& p_search,
        const std::string& p_replace );


    const std::string WHITESPACE = " \t\n\r";

    std::string Trim( const std::string& p_string );
    std::string RTrim(const std::string& s,u_int len);

    std::string ParseWord( const std::string& p_string, int p_index );
    std::string RemoveWord( const std::string& p_string, int p_index );

    template< typename type >
    inline void insert( std::ostream& s, const type& t )  {  s << t; }
    template< typename type >
    inline type& extract( std::istream& s, type& t )  {  s >> t; return t; }

    std::string UpperCase( const std::string& p_string );
    std::string LowerCase( const std::string& p_string );

    template< typename type >
    inline std::string tostring( const type& p_type, size_t p_width = 0 )
    {
        std::stringstream str;
        insert( str, p_type );

        // if string is larger than width, just return the whole thing.
        if( str.str().size() >= p_width )
            return str.str();

        // add as many spaces as needed after the string if not.
        return str.str() + std::string( p_width - str.str().size(), ' ' );
    }

    template< typename type >
    inline type totype( const std::string& p_string )
    {
        std::stringstream str( p_string );
        type t;
        extract( str, t );
        return t;
    }

    struct lt_strcmp
    {
        bool operator()(LPCSTR s1, LPCSTR s2) const 
        {
            return ::strcmp(s1, s2) < 0;
        }
    };


    struct lt_strcasecmp
    {
        bool operator()(LPCSTR s1, LPCSTR s2) const 
        {
            return ::strcasecmp(s1, s2) < 0;
        }
    };
#endif // end of __STRING_UTIL__
